﻿namespace Bean.Entity.Dto.PolicyPushDto;

/// <summary>
/// 同程特殊政策推送
/// </summary>
public class OtaLySpecialPolicyPushDto : OtaLyBasicPolicyPushDto
{
    /// <summary>
    /// 
    /// </summary>
    private OtaLySpecialPolicyPushDto()
    {
    }

    /// <summary>
    /// 资源规则类型；默认1-平台定制；枚举：1-平台定制、2-代理自定义
    /// </summary>
    public int resRuleType { get; private set; } = 1;

    /// <summary>
    /// 同程定制运价规则；当“resRuleType=1”时才可以填；针对N人起订、性别、年龄等特殊限制资源，有此类资源需要投放请联系客户经理获取
    /// </summary>
    public string fareRule { get; set; }

    /// <summary>
    /// 资源对年龄限制；默认空；当“resRuleType=2”时，才可以填（具体值请参考后台页面）
    /// </summary>
    public string resAgeType { get; set; }

    /// <summary>
    /// 资源对人数限制；默认空；当“resRuleType=2”时，才可以填（具体值请参考后台页面）
    /// </summary>
    public string resNumberType { get; set; }

    /// <summary>
    /// 资源对证件限制；默认空；当“resRuleType=2”时，才可以填（具体值请参考后台页面）
    /// </summary>
    public string resCardType { get; set; }

    /// <summary>
    /// 舱位名称；名称规范："经济舱"，"特殊经济舱"，"头等舱"，"商务舱"
    /// </summary>
    public string cabinName { get; set; }

    /// <summary>
    /// 是否是团队票；默认0-否；枚举：0-否、1-是
    /// </summary>
    public int isTeamTicket { get; set; } = 0;

    /// <summary>
    /// 指定舱位；占用时的舱位代码，不指定无需填写
    /// </summary>
    public string particularCabinCode { get; set; }

    /// <summary>
    /// 计价类型；枚举：1-适用舱位、2-固定价格
    /// </summary>
    public int valuationType { get; set; }

    /// <summary>
    /// 价格运算符；枚举：2-加、3-减 、4-先减比例后加金额、5-先加比例后减金额 当”valuationType=1“时 ，则actionType必传； 当”valuationType=2“时 ，则actionType不传
    /// </summary>
    public int? actionType { get; set; }

    /// <summary>
    /// 加减基准；枚举：2-适用舱位、3-基准舱位； 当“valuationType=1 ”时，则addSubtractBaseType必传； 当“valuationType=2 ”时，则addSubtractBaseType不传
    /// </summary>
    public int? addSubtractBaseType { get; set; }

    /// <summary>
    /// 加减折扣；默认0.00；大于0的两位小数；如10%，传10，录入系统后会自动除以100； 当“valuationType=2”时，不传
    /// </summary>
    public decimal addSubtractDiscount { get; set; } = 0M;

    /// <summary>
    /// 加减金额；默认0；大于等于0整数； 当“valuationType=2”，不传
    /// </summary>
    public decimal addSubtractMoney { get; set; } = 0;

    /// <summary>
    /// 固定价格；大于0整数（只支持整数）；当“valuationType=2”时，则fixedTotalPrice必传；当“valuationType=1”时，则fixedTotalPrice不传
    /// </summary>
    public int? fixedTotalPrice { get; set; }

    /// <summary>
    /// 计价逻辑；默认：3-四舍五入到十位； 枚举：1-逢一进十、2-进位到个位、3-四舍五入到十位、4-舍去个位、5-四舍五入到个位
    /// </summary>
    public int calculationLogic { get; set; } = 3;

    /// <summary>
    /// 卖价下限
    /// </summary>
    public int sellPriceLowerLimit { get; set; } = 0;

    /// <summary>
    /// 卖价上限
    /// </summary>
    public int sellPriceUpperLimit { get; set; } = 1000;

    /// <summary>
    /// 是否验价； 枚举：0-不验价 、1-验价
    /// </summary>
    public int isVerifyPrice { get; set; } = 1;

    /// <summary>
    /// 上浮金额； 可不传； 仅支持正整数
    /// </summary>
    public decimal? floatPrice { get; set; }

    /// <summary>
    /// 验价office号； 用于验价的Office号，大写，最多支持15个字符
    /// </summary>
    public string verifyPriceOffice { get; set; }

    /// <summary>
    /// 销售适用班期； 默认：[1,2,3,4,5,6,7]
    /// </summary>
    public List<int> saleWeekSegmentList { get; set; } = new List<int> { 1, 2, 3, 4, 5, 6, 7 };

    /// <summary>
    /// 同舱多价取值, 默认0: 0:优先FD，1:优先NFD
    /// </summary>
    public int sameCabinPriceType { get; set; } = 0;

    /// <summary>
    /// 适用舱运价取值； 默认：0-最高值；枚举：0-最高值 、1-最低值；如果投放“非指定运价”此字段代表“适用舱NFD的取值”
    /// </summary>
    public int nfdType { get; set; } = 0;

    /// <summary>
    /// 运价类型； 默认：空字符串 - 非指定运价； 枚举：空字符串 - 非指定运价、 "1"-公布运价、 "2"-私有运价 、"3"-直减运价、 "4"-中转运价、"5"-官网B2C运价,、"6"-往返RT运价、"7"-官网往返运价、"8"-官网联程运价、"9"-官网B2B运价、"10"-不可单售运价。多个运价类型之间用英文逗号分隔。
    /// </summary>
    public string farePriceType { get; set; }

    /// <summary>
    /// 特殊运价；可从ebook后台复制
    /// </summary>
    public string productType { get; set; }

    /// <summary>
    /// 成人返点来源； 默认：0-政策录入； 枚举：0-政策录入、1-官网接口
    /// </summary>
    public int adultRebateSource { get; set; } = 0;

    #region 特殊政策比通用政策多出来的字段

    // "resRuleType":1,//类型：Number  可有字段  备注：资源规则类型； 默认：1-平台定制； 枚举：1-平台定制、 2-代理自定义；
    //"fareRule":"CFR100002",//类型：String  可有字段  备注：同程定制运价规则； 当“resRuleType=1”时才可以填； 针对N人起订、性别、年龄等特殊限制资源，有此类资源需要投放请联系客户经理获取；
    //"resAgeType":"Mock",//类型：String  可有字段  备注：资源对年龄限制； 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
    //      "resNumberType":"Mock",                //类型：String  可有字段  备注：资源对人数限制； 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
    //            "resCardType":"Mock",                //类型：String  可有字段  备注：资源对证件限制； 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
    // "cabinName":"经济舱",                //类型：String  可有字段  备注：舱位名称； 名称规范："经济舱"，"特殊经济舱"，"头等舱"，"商务舱"；
    //         "IsTeamTicket":0,                //类型：Number  可有字段  备注：是否是团队票； 默认：0-否； 枚举：0-否、1-是；
    // "particularCabinCode":"mock",                //类型：String  可有字段  备注：指定舱位； 占座时的舱位代码，不指定无需填写；
    // "valuationType":1,                //类型：Number  必有字段  备注：计价类型； 枚举：1-适用舱位、2-固定价格
    //           "actionType":3,                //类型：Number  可有字段  备注：价格运算符； 枚举：2-加、3-减 、4-先减比例后加金额、5-先加比例后减金额 当”valuationType=1“时 ，则actionType必传； 当”valuationType=2“时 ，则actionType不传；
    //   "addSubtractBaseType":3,                //类型：Number  可有字段  备注：加减基准； 枚举：2-适用舱位、3-基准舱位； 当“valuationType=1 ”时，则addSubtractBaseType必传； 当“valuationType=2 ”时，则addSubtractBaseType不传；
    //            "addSubtractDiscount":1,                //类型：Number  可有字段  备注：加减折扣； 默认0.00； 大于0的两位小数； 如10%，传10，录入系统后会自动除以100； 当“valuationType=2”时，不传；
    //         "addSubtractMoney":0,                //类型：Number  可有字段  备注：加减金额； 默认0； 大于等于0整数； 当“valuationType=2”，不传；
    //      "fixedTotalPrice":0,                //类型：Number  可有字段  备注：固定价格；大于0整数（只支持整数）；当“valuationType=2”时，则fixedTotalPrice必传；当“valuationType=1”时，则fixedTotalPrice不传；
    //    "calculationLogic":3,                //类型：Number  可有字段  备注：计价逻辑； 默认：3-四舍五入到十位； 枚举：1-逢一进十、2-进位到个位、3-四舍五入到十位、4-舍去个位、5-四舍五入到个位
    //            "sellPriceLowerLimit":0,                //类型：Number  可有字段  备注：卖价下限
    //            "sellPriceUpperLimit":1000,                //类型：Number  可有字段  备注：卖价上限
    //        "isVerifyPrice":1,                //类型：Number  可有字段  备注：是否验价； 枚举：0-不验价 、1-验价；
    //            "floatPrice":1,                //类型：Number  可有字段  备注：上浮金额； 可不传； 仅支持正整数；
    //     "verifyPriceOffice":"SZV123",                //类型：String  可有字段  备注：验价office号； 用于验价的Office号，大写，最多支持15个字符；
    //"saleWeekSegmentList": - [                //类型：Array  可有字段  备注：销售适用班期； 默认：[1,2,3,4,5,6,7] ],

    //    "sameCabinPriceType":0,                //类型：Number  可有字段  备注：同舱多价取值, 默认0: 0:优先FD，1:优先NFD
    // "nfdType":0,                //类型：Number  可有字段  备注：适用舱运价取值； 默认：0-最高值；枚举：0-最高值 、1-最低值；如果投放“非指定运价”此字段代表“适用舱NFD的取值”
    // "farePriceType":"3",                //类型：String  可有字段  备注：运价类型； 默认：空字符串 - 非指定运价； 枚举：空字符串 - 非指定运价、 "1"-公布运价、 "2"-私有运价 、"3"-直减运价、 "4"-中转运价、"5"-官网B2C运价,、"6"-往返RT运价、"7"-官网往返运价、"8"-官网联程运价、"9"-官网B2B运价、"10"-不可单售运价。多个运价类型之间用英文逗号分隔。
    //       "productType":"MUTWO",                //类型：String  可有字段  备注：特殊运价；可从ebook后台复制

    //  "adultRebateSource":0                //类型：Number  可有字段  备注：成人返点来源； 默认：0-政策录入； 枚举：0-政策录入、1-官网接口；

    #endregion


    public new class Builder : OtaLyBasicPolicyPushDto.Builder
    {
        public Builder()
        {
            _dto = new OtaLySpecialPolicyPushDto();
        }

        /// <summary>
        /// 资源规则类型；
        /// 默认：1-平台定制； 枚举：1-平台定制、 2-代理自定义；
        /// </summary>
        /// <returns></returns>
        public Builder SetResRuleType(int resRuleType = 1)
        {
            ((OtaLySpecialPolicyPushDto)_dto).resRuleType = resRuleType;
            return this;
        }

        /// <summary>
        /// 同程定制运价规则
        /// resRuleType=1”时才可以填
        /// </summary>
        /// <param name="fareRule"></param>
        /// <returns></returns>
        public Builder SetFareRule(string fareRule)
        {
            if (((OtaLySpecialPolicyPushDto)_dto).resRuleType == 1)
            {
                ((OtaLySpecialPolicyPushDto)_dto).fareRule = fareRule;
            }

            return this;
        }

        /// <summary>
        /// 资源对年龄限制
        /// 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
        /// </summary>
        /// <param name="resAgeType"></param>
        /// <returns></returns>
        public Builder SetResAgeType(string resAgeType = "")
        {
            if (((OtaLySpecialPolicyPushDto)_dto).resRuleType == 2)
            {
                ((OtaLySpecialPolicyPushDto)_dto).resAgeType = resAgeType;
            }

            return this;
        }

        /// <summary>
        /// 资源对人数限制； 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
        /// </summary>
        /// <param name="resNumberType"></param>
        /// <returns></returns>
        public Builder SetResNumberType(string resNumberType = "")
        {
            if (((OtaLySpecialPolicyPushDto)_dto).resRuleType == 2)
            {
                ((OtaLySpecialPolicyPushDto)_dto).resNumberType = resNumberType;
            }

            return this;
        }

        /// <summary>
        /// 资源对证件限制； 默认空； 当“resRuleType=2”时，才可以填（具体值请参考后台页面）；
        /// </summary>
        /// <param name="resCardType"></param>
        /// <returns></returns>
        public Builder SetResCardType(string resCardType = "")
        {
            if (((OtaLySpecialPolicyPushDto)_dto).resRuleType == 2)
            {
                ((OtaLySpecialPolicyPushDto)_dto).resCardType = resCardType;
            }

            return this;
        }

        /// <summary>
        /// 舱位名称；
        /// 名称规范："经济舱"，"特殊经济舱"，"头等舱"，"商务舱"；
        /// </summary>
        /// <param name="cabinName"></param>
        /// <returns></returns>
        public Builder SetCabinName(string cabinName)
        {
            ((OtaLySpecialPolicyPushDto)_dto).cabinName = cabinName;

            return this;
        }

        /// <summary>
        /// 是否是团队票
        /// 默认：0-否； 枚举：0-否、1-是；
        /// </summary>
        /// <param name="isTeamTicket"></param>
        /// <returns></returns>
        public Builder SetIsTeamTicket(int isTeamTicket = 0)
        {
            ((OtaLySpecialPolicyPushDto)_dto).isTeamTicket = isTeamTicket;
            return this;
        }

        /// <summary>
        ///指定舱位代码
        ///  
        /// </summary>
        /// <param name="particularCabinCode"></param>
        /// <returns></returns>
        public Builder SetParticularCabinCode(string particularCabinCode = "")
        {
            ((OtaLySpecialPolicyPushDto)_dto).particularCabinCode = particularCabinCode;
            return this;
        }

        /// <summary>
        /// 计价类型
        /// 枚举：1-适用舱位、2-固定价格
        /// </summary>
        /// <returns></returns>
        public Builder SetValuationType(int valuationType)
        {
            if (string.IsNullOrWhiteSpace(valuationType.ToString()))
            {
                throw new ArgumentException("计价类型不能为空", nameof(valuationType));
            }

            if (!new[] { 1, 2 }.Contains(valuationType))
            {
                throw new ArgumentException("计价类型必须是有效的值: 1-适用舱位、2-固定价格", nameof(valuationType));
            }

            ((OtaLySpecialPolicyPushDto)_dto).valuationType = valuationType;
            return this;
        }

        /// <summary>
        /// 价格运算符
        /// 枚举：2-加、3-减 、4-先减比例后加金额、5-先加比例后减金额
        /// 当”valuationType=1“时 ，则actionType必传； 当”valuationType=2“时 ，则actionType不传
        /// </summary>
        /// <returns></returns>
        public Builder SetActionType(int? actionType)
        {
            if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 1 &&
                actionType.HasValue)
            {
                throw new ArgumentException("计价类型为1时，价格运算符不能为空", nameof(actionType));
            }
            else if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 2)
            {
                ((OtaLySpecialPolicyPushDto)_dto).actionType = null;
            }
            else
            {
                ((OtaLySpecialPolicyPushDto)_dto).actionType = actionType;
            }

            return this;
        }

        /// <summary>
        /// 加减基准
        /// 2-适用舱位、3-基准舱位； 当“valuationType=1 ”时，则addSubtractBaseType必传；
        /// 当“valuationType=2 ”时，则addSubtractBaseType不传；    
        /// </summary>
        /// <returns></returns>
        public Builder SetAddSubtractBaseType(int? addSubtractBaseType)
        {
            if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 1 && addSubtractBaseType.HasValue)
            {
                throw new ArgumentException("计价类型为1时，加减基准不能为空", nameof(actionType));
            }
            else if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 2)
            {
                ((OtaLySpecialPolicyPushDto)_dto).addSubtractBaseType = null;
            }
            else
            {
                ((OtaLySpecialPolicyPushDto)_dto).addSubtractBaseType = addSubtractBaseType;
            }

            return this;
        }

        /// <summary>
        /// 加减折扣
        /// </summary>
        /// <returns></returns>
        public Builder SetAddSubtractDiscount(decimal addSubtractDiscount = 0M)
        {
            ((OtaLySpecialPolicyPushDto)_dto).addSubtractDiscount = addSubtractDiscount;
            return this;
        }

        /// <summary>
        /// 加减金额
        /// 当“valuationType=2”，不传；
        /// </summary>
        /// <param name="addSubtractMoney"></param>
        /// <returns></returns>
        public Builder SetAddSubtractMoney(decimal addSubtractMoney = 0M)
        {
            ((OtaLySpecialPolicyPushDto)_dto).addSubtractMoney = addSubtractMoney;
            return this;
        }

        /// <summary>
        /// 固定价格
        /// valuationType=2”时，则fixedTotalPrice必传；当“valuationType=1”时，则fixedTotalPrice不传；
        /// </summary>
        /// <returns></returns>
        public Builder SetFixedTotalPrice(int? fixedTotalPrice)
        {
            if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 2 && fixedTotalPrice.HasValue)
            {
                throw new ArgumentException("计价类型为2时，固定价格不能为空", nameof(fixedTotalPrice));
            }
            else if (((OtaLySpecialPolicyPushDto)_dto).valuationType == 1 && fixedTotalPrice.HasValue)
            {
                ((OtaLySpecialPolicyPushDto)_dto).fixedTotalPrice = null;
            }
            else
            {
                ((OtaLySpecialPolicyPushDto)_dto).fixedTotalPrice = fixedTotalPrice;
            }

            return this;
        }

        /// <summary>
        /// 计价逻辑；
        /// 默认：3-四舍五入到十位； 枚举：1-逢一进十、2-进位到个位、3-四舍五入到十位、4-舍去个位、5-四舍五入到个位
        /// </summary>
        /// <param name="calculationLogic"></param>
        /// <returns></returns>
        public Builder SetCalculationLogic(int calculationLogic = 3)
        {
            ((OtaLySpecialPolicyPushDto)_dto).calculationLogic = calculationLogic;
            return this;
        }

        /// <summary>
        /// 卖价下限
        /// </summary>
        /// <returns></returns>
        public Builder SetSellPriceLowerLimit(int sellPriceLowerLimit = 0)
        {
            ((OtaLySpecialPolicyPushDto)_dto).sellPriceLowerLimit = sellPriceLowerLimit;
            return this;
        }

        /// <summary>
        /// 卖价上限
        /// </summary>
        /// <param name="sellPriceUpperLimit"></param>
        /// <returns></returns>
        public Builder SetSellPriceUpperLimit(int sellPriceUpperLimit)
        {
            ((OtaLySpecialPolicyPushDto)_dto).sellPriceUpperLimit = sellPriceUpperLimit;
            return this;
        }

        /// <summary>
        /// 是否验价
        /// </summary>
        /// <param name="isVerifyPrice"></param>
        /// <returns></returns>
        public Builder SetIsVerifyPrice(int isVerifyPrice = 1)
        {
            ((OtaLySpecialPolicyPushDto)_dto).isVerifyPrice = isVerifyPrice;
            return this;
        }

        /// <summary>
        /// 上浮金额
        /// </summary>
        /// <returns></returns>
        public Builder SetFloatPrice(decimal? floatPrice)
        {
            ((OtaLySpecialPolicyPushDto)_dto).floatPrice = floatPrice;
            return this;
        }

        /// <summary>
        /// 验价office号； 用于验价的Office号，大写，最多支持15个字符
        /// </summary>
        /// <returns></returns>
        public Builder SetVerifyPriceOffice(string verifyPriceOffice)
        {
            ((OtaLySpecialPolicyPushDto)_dto).verifyPriceOffice = verifyPriceOffice;
            return this;
        }

        /// <summary>
        /// 销售适用班期
        /// </summary>
        /// <returns></returns>
        public Builder SetSaleWeekSegmentList(List<int> saleWeekSegmentList)
        {
            ((OtaLySpecialPolicyPushDto)_dto).saleWeekSegmentList =
                saleWeekSegmentList ?? [1, 2, 3, 4, 5, 6, 7];
            return this;
        }

        /// <summary>
        /// 同舱多价取值, 默认0: 0:优先FD，1:优先NFD
        /// </summary>
        /// <param name="sameCabinPriceType"></param>
        /// <returns></returns>
        public Builder SetSameCabinPriceType(int sameCabinPriceType = 0)
        {
            ((OtaLySpecialPolicyPushDto)_dto).sameCabinPriceType = sameCabinPriceType;
            return this;
        }

        /// <summary>
        /// 适用舱运价取值；
        /// 默认：0-最高值；枚举：0-最高值 、1-最低值；如果投放“非指定运价”此字段代表“适用舱NFD的取值”
        /// </summary>
        /// <param name="nfdType"></param>
        /// <returns></returns>
        public Builder SetNfdType(int nfdType = 0)
        {
            ((OtaLySpecialPolicyPushDto)_dto).nfdType = nfdType;
            return this;
        }

        /// <summary>
        /// 运价类型
        /// 默认：空字符串 - 非指定运价； 枚举：空字符串 - 非指定运价、 "1"-公布运价、 "2"-私有运价 、
        /// "3"-直减运价、 "4"-中转运价、"5"-官网B2C运价,、"6"-往返RT运价、"7"-官网往返运价、"8"-官网联程运价、"9"-官网B2B运价、"10"-不可单售运价。多个运价类型之间用英文逗号分隔。
        /// </summary>
        /// <param name="farePriceType"></param>
        /// <returns></returns>
        public Builder SetFarePriceType(string farePriceType = "")
        {
            ((OtaLySpecialPolicyPushDto)_dto).farePriceType = farePriceType;
            return this;
        }

        /// <summary>
        /// 特殊运价；可从ebook后台复制
        /// </summary>
        /// <param name="productType"></param>
        /// <returns></returns>
        public Builder SetProductType(string productType)
        {
            ((OtaLySpecialPolicyPushDto)_dto).productType = productType;
            return this;
        }

        /// <summary>
        /// 成人返点来源； 默认：0-政策录入；
        /// 枚举：0-政策录入、1-官网接口
        /// </summary>
        /// <returns></returns>
        public Builder SetAdultRebateSource(int adultRebateSource = 0)
        {
            ((OtaLySpecialPolicyPushDto)_dto).adultRebateSource = adultRebateSource;
            return this;
        }

        /// <summary>
        /// 构建
        /// </summary>
        /// <returns></returns>
        public new OtaLySpecialPolicyPushDto Build()
        {
            return (OtaLySpecialPolicyPushDto)_dto;
        }
    }
}